﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.DAL.DTOs;
using System.Data;
using Microsoft.Office.Server.Search.Administration;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Search.Query;
using MS.InformationManagement.DAL.DocumentCenter;
using System.Xml.Serialization;
using System.IO;
using MS.InformationManagement.DAL.DocumentCenter.Search.Enums;
using MS.InformationManagement.Support;
using MS.InformationManagement.Core.Support;
using MS.InformationManagement.Support.Constants;

namespace MS.InformationManagement.BLL.SimpleSearch
{
    public class SimpleSearchBLL
    {

        public List<RadicadoSearchDTO> ExecuteSimpleSearch(string searchCriteria, int pageIndex, int pageSize, out int toltalRecords, out int totalExecutionTime) 
        {

            List<RadicadoSearchDTO> foundElements = new List<RadicadoSearchDTO>();
            int toTal = 0;
            int totalExecution = 0;
 
            int startRow = pageIndex * pageSize;
            SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(SPContext.Current.Site));
            FullTextSqlQuery query = new FullTextSqlQuery(proxy);
            string filtros = string.Format("AND (Title LIKE '%{0}%' OR Description LIKE '%{0}%' OR Write LIKE '%{0}%' OR Path LIKE '%{0}% '" +
            "OR IMDocumentApellido1 LIKE '%{0}%' OR IMDocumentApellido2 LIKE '%{0}%' OR IMDocumentAsunto LIKE '%{0}%' OR IMDocumentDepartment LIKE '%{0}%' " +
            "OR IMDocumentFolios LIKE '%{0}%' OR IMDocumentFoliosAnex LIKE '%{0}%' OR IMDocumentNITCedula LIKE '%{0}%' OR IMDocumentNombres LIKE '%{0}%' " +
            "OR IMDocumentRadicado LIKE '%{0}%' OR IMDocumentRazon LIKE '%{0}%' OR IMDocumentRepresentante LIKE '%{0}%' OR IMDocumentStatus LIKE '%{0}%' " +
            "OR IMDocumentTipoRadicado LIKE '%{0}%' OR IMDocumentUsuarioActual LIKE '%{0}%' OR IMDocumentRemitenteDestinatario LIKE '%{0}%') ", searchCriteria);
            string queryFilter = !string.IsNullOrEmpty(searchCriteria) ? filtros : string.Empty;
            query.QueryText = string.Format(@"SELECT    Title,
                                                        Description,
                                                        Write, 
                                                        Path, 
                                                        IMDocumentApellido1, 
                                                        IMDocumentApellido2, 
                                                        IMDocumentAsunto, 
                                                        IMDocumentDepartment, 
                                                        IMDocumentFolios, 
                                                        IMDocumentFoliosAnex, 
                                                        IMDocumentNITCedula, 
                                                        IMDocumentNombres, 
                                                        IMDocumentRadicado, 
                                                        IMDocumentRazon, 
                                                        IMDocumentRepresentante, 
                                                        IMDocumentStatus, 
                                                        IMDocumentTipoRadicado, 
                                                        IMDocumentUsuarioActual, 
                                                        IMItemId,
                                                        IMDocumentRemitenteDestinatario FROM Scope() WHERE ( (""SCOPE"" = 'Information Management - Documents') ) {0} ORDER BY ""Rank"" DESC", queryFilter);
            query.RowLimit = pageSize;
            query.StartRow = startRow;
            query.TrimDuplicates = true;
            query.ResultTypes |= ResultType.RelevantResults;
            query.ResultsProvider = Microsoft.Office.Server.Search.Query.SearchProvider.SharepointSearch;
            query.KeywordInclusion = KeywordInclusion.AnyKeyword;

            ResultTableCollection results = query.Execute();
            ResultTable relevantResults = results[ResultType.RelevantResults];
            DataTable dtResults = new DataTable();
            dtResults.Load(relevantResults, LoadOption.OverwriteChanges);

            foundElements = (from DataRow row in dtResults.Rows
                                                        select new RadicadoSearchDTO
                                                        {
                                                            DescriptionText = row.IsNull(1) ? string.Empty : row.Field<string>(1),
                                                            Title = row.IsNull(0) ? string.Empty : row.Field<string>(0),
                                                            //Path = "/sites/docs/_layouts/MS.InformationManagement.WP/" + getForm(row.Field<string>(16)) + "?strategy=edit&ListId=" + UserLibraryHelper.GetUserList(row.Field<string>(3).GetUserListNameFromUrl()).ID.ToString() + "&IsDlg=1&ID=" + row.Field<string>(18),
                                                            Path = (row.IsNull(18) || row.IsNull(3)) ? string.Empty : string.Format("/sites/docs/_layouts/listform.aspx?PageType=6&ListId={0:B}&ID={1}"
                                                            , UserLibraryHelper.GetLibrary(row.Field<string>(3).GetUserListNameFromUrl()).ID, row.Field<string>(18)),
                                                            EntryDate = row.IsNull(2) ? new Nullable<DateTime>() : row.Field<DateTime>(2),
                                                            LastName1 = !row.IsNull(4) ? row.Field<string>(4) : string.Empty,
                                                            LastName2 = !row.IsNull(5) ? row.Field<string>(5) : string.Empty,
                                                            Subject = !row.IsNull(6) ? row.Field<string>(6) : "No disponible",
                                                            Department = !row.IsNull(7) ? row.Field<string>(7) : string.Empty,
                                                            Folios = !row.IsNull(8) ? row.Field<double>(8) : 0,
                                                            Annexes = !row.IsNull(9) ? row.Field<double>(9) : 0,
                                                            PersonDocumentNumber = !row.IsNull(12) ? row.Field<string>(10) : string.Empty,
                                                            FirstName = !row.IsNull(11) ? row.Field<string>(11) : string.Empty,
                                                            DocumentNumber = !row.IsNull(12) ? row.Field<string>(12) : string.Empty,
                                                            CompanyName = !row.IsNull(13) ? row.Field<string>(13) : string.Empty,
                                                            CompanyLegalRepresentative = !row.IsNull(14) ? row.Field<string>(14) : string.Empty,
                                                            DocumentStatus = !row.IsNull(15) ? row.Field<string>(15) : "No disponible",
                                                            DocumentType = !row.IsNull(16) ? row.Field<string>(16) : "No disponible",
                                                            RemitenteDestinatario = !row.IsNull(19) ? row.Field<string>(19) : "No dispobible"
                                                        }).ToList();

            toTal = relevantResults.TotalRows;
            totalExecution = results.ElapsedTime;

            toltalRecords = toTal;
            totalExecutionTime = totalExecution;

            return foundElements;
        }

        public static IEnumerable<HistorialDeBusqueda> GetPastSearch(int userID, int pageIndex, int pageSize, out int totalRecords)
        {
            int startingIndex = pageIndex * pageSize;
            IEnumerable<HistorialDeBusqueda> searchHistoryItems = null;
            using (DCDocumentCenterDataContext dtctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                searchHistoryItems = (from item in dtctx.HistorialesDeBusquedas.ScopeToFolder("", true)
                                      where item.UsuarioId.Equals(userID)
                                      orderby item.FechaDeBúsqueda descending
                                      select item);
                totalRecords = searchHistoryItems.Count();
                searchHistoryItems = searchHistoryItems.Skip(startingIndex).Take(pageSize);
            }
            return searchHistoryItems;
        }

        public static HistorialDeBusqueda SaveSimpleSearchHistory(string searchCriteria)
        {
            HistorialDeBusqueda newItem = null;
            string userDomain =SPContext.Current.Web.CurrentUser.LoginName;
            string username = SPContext.Current.Web.CurrentUser.LoginName.GetUserWithOutDomain();

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite currentSite = new SPSite(SPContext.Current.Site.ID))
                {
                    using (SPWeb currentWeb = currentSite.OpenWeb())
                    {
                        currentWeb.AllowUnsafeUpdates = true;
                        SearchConfig searchConfig = new SearchConfig { SearchType = SearchType.Simple, SimpleSearchCriteria = searchCriteria };             
                        string targetFolderUrl = string.Format("{0}/Historiales de Busquedas/{1}", currentWeb.Url, username);
                        SPFolder targetFolder = SPContext.Current.Web.GetFolder(targetFolderUrl);
                        SPList targetList = currentWeb.Lists.TryGetList("Historiales de Busquedas");

                        if (!targetFolder.Exists && targetList != null)
                          targetFolder = targetList.RootFolder.SubFolders.Add(username);

                        //Saving new search entry
                        SPListItem newEntry = targetList.Items.Add();
                        newEntry[SPBuiltInFieldId.Title] = Guid.NewGuid().ToString();
                        newEntry[CustomSiteColumns.SEARCH_OWNER] = currentWeb.Users[userDomain];
                        //newEntry[SPBuiltInFieldId.FileDirRef] = targetFolder.Url;
                        newEntry[CustomSiteColumns.SEARCH_DATE] = DateTime.Now;
                        newEntry[CustomSiteColumns.SEARCH_CONFIG] = serializeObject(searchConfig);
                        newEntry.Update();

                        currentWeb.AllowUnsafeUpdates = false;
                    }
                }
            });

            return newItem;
        }

        #region Private Methods

        private static String serializeObject(SearchConfig value)
        {
            XmlSerializer tSerializer = new XmlSerializer(typeof(SearchConfig));
            using (StringWriter sWriter = new StringWriter())
            {
                tSerializer.Serialize(sWriter, value);
                return sWriter.ToString();
            }
        }



        private static string getForm(string documentKind)
        {
            switch (documentKind)
            {
                case GlobalConstants.METADATA_TERM_TIPO_RADICADO_ENTRADA: return "InsertarRadicado.aspx";
                case GlobalConstants.METADATA_TERM_TIPO_RADICADO_SALIDA: return "InsertarRadicadoSalida.aspx";
                case GlobalConstants.METADATA_TERM_TIPO_INTERNO: return "InsertarRadicadoInterno.aspx";
                default: return string.Empty;
            }
        }

        #endregion

    }
}
